package com.yanqu.road.server.manger.player;

import com.yanqu.road.entity.player.UserBaseInfo;
import com.yanqu.road.logic.bussiness.player.UserMineWarBussiness;
import com.yanqu.road.logic.thread.ThreadTaskManger;
import com.yanqu.road.logic.pb.BattlePb;
import com.yanqu.road.server.pb.MineWarPb;
import com.yanqu.road.logic.pb.PatronsPb;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.entity.config.battle.BattleResult;
import com.yanqu.road.entity.enums.*;
import com.yanqu.road.entity.minewar.*;
import com.yanqu.road.entity.player.UserInfo;
import com.yanqu.road.entity.player.UserPatrons;
import com.yanqu.road.pb.minewar.MineWarProto;
import com.yanqu.road.pb.patrons.PatronsProto;
import com.yanqu.road.server.TempMgr;
import com.yanqu.road.server.GameServer;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.patrons.PatronsModule;
import com.yanqu.road.server.gameplayer.module.player.CurrencyModule;
import com.yanqu.road.server.gameplayer.module.player.MineWarModule;
import com.yanqu.road.server.logic.mail.MailManager;
import com.yanqu.road.server.manger.ConfigMgr;
import com.yanqu.road.server.logic.battle.BattleManager;
import com.yanqu.road.server.manger.MultipleLanguageMgr;
import com.yanqu.road.server.manger.config.MineWarConfigMgr;
import com.yanqu.road.server.manger.config.SystemOpenMgr;
import com.yanqu.road.server.manger.log.LogMgr;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.utils.UUIDHelper;
import com.yanqu.road.utils.executor.GeneralTask;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 寻宝
 */
public class MineWarMgr extends TempMgr {

    private static Logger logger = LogManager.getLogger(MineWarMgr.class.getName());

    private static final Object lockObj = new Object();

    private static Map<Integer, Map<Integer, UserMinePit>> userMinePitMap;

    private static List<UserMinePit> needUpdateUserMinePitList = new ArrayList<>();

    private static Map<Long, List<MineWarRecord>> mineWarRecordMap;

    private static List<MineWarRecord> needAddRecordList;

    private static LinkedList<MineWarNotice> mineWarNoticeList;

    private static List<MineWarNotice> needAddNoticeList;

    private static Map<Long, UserMineData> userMineDataMap;

    private static ThreadTaskManger threadTaskManger;

    private static AtomicInteger actionId = new AtomicInteger(1);

    @Override
    public boolean init() throws Exception {
        return reload();
    }

    @Override
    public boolean reloadConfig() throws Exception {
        return true;
    }

    @Override
    public boolean stop() {
        return false;
    }

    public boolean save() {
        List<UserMinePit> tempPitList;
        synchronized (needUpdateUserMinePitList) {
            tempPitList = new ArrayList<>(needUpdateUserMinePitList);
            needUpdateUserMinePitList = new ArrayList<>();
        }
        if (tempPitList.size() > 0) {
            UserMineWarBussiness.updateUserMinePitList(tempPitList);
        }
        //保存记录
        List<MineWarRecord> tempNeedAddRecord;
        synchronized (needAddRecordList) {
            tempNeedAddRecord = new ArrayList<>(needAddRecordList);
            needAddRecordList = new ArrayList<>();
        }
        if (tempNeedAddRecord.size() > 0) {
            UserMineWarBussiness.addMineWarRecordList(tempNeedAddRecord);
        }
        List<MineWarNotice> tempNeedAddNotice = new ArrayList<>();
        synchronized (needAddNoticeList){
            tempNeedAddNotice.addAll(needAddNoticeList);
            needAddNoticeList = new ArrayList<>();
        }
        if(tempNeedAddNotice.size() > 0){
            UserMineWarBussiness.addMineWarNoticeList(tempNeedAddNotice);
        }
        return true;
    }

    @Override
    public boolean reloadData() {
        if(null != threadTaskManger) {
            threadTaskManger = new ThreadTaskManger(4, "mineWarTaskManger");
        }
        userMinePitMap = UserMineWarBussiness.getUserMinePitMap();
        userMineDataMap = UserMineWarBussiness.getUserMineDataMap();
        boolean isChange = false;
        for(Map.Entry<Integer, Map<Integer, MinePitInfo>> dataEntry : MineWarConfigMgr.getMinePitInfoMap().entrySet()){
            Map<Integer, UserMinePit> minePitMap = getUserMinePitMap(dataEntry.getKey());
            if(null == minePitMap){
                minePitMap = new ConcurrentHashMap<>();
            }
            if(minePitMap.size() < dataEntry.getValue().size()){
                UserMineWarBussiness.initUserMinePitMap(dataEntry.getValue(), minePitMap);
                isChange = true;
            }
        }
        if(isChange){
            userMinePitMap = UserMineWarBussiness.getUserMinePitMap();
        }
        refreshMineStation();
        //加载记录信息
        mineWarRecordMap = UserMineWarBussiness.getMineWarRecordMap();
        needAddRecordList = new ArrayList<>();
        //加载通告信息
        mineWarNoticeList = UserMineWarBussiness.getMineWarNoticeList(GameConfig.MINE_WAR_MAX_NOTICE_COUNT);
        needAddNoticeList = new ArrayList<>();
        return true;
    }

    public static void setUserMineData(UserMineData userMineData){
        if(null != userMineData) {
            userMineDataMap.put(userMineData.getUserId(), userMineData);
        }
    }

    private static void refreshMineStation(){
        for(Map.Entry<Integer, Map<Integer, MineStationInfo>> dateEntry : MineWarConfigMgr.getMineStationMap().entrySet()){
            for(MineStationInfo stationInfo : dateEntry.getValue().values()){
                changeMineStation(stationInfo);
            }
        }
    }

    public static List<UserMinePit> getUserMinePitList(int mineType, int startPitId, int endPitId){
        List<UserMinePit> pitList = new ArrayList<>();
        Map<Integer, UserMinePit> minePitMap = getUserMinePitMap(mineType);
        if(null != minePitMap){
            for(int i = startPitId; i <= endPitId; i++){
                pitList.add(minePitMap.get(i));
            }
        }
        return pitList;
    }

    public static void addTask(GeneralTask task) {
        threadTaskManger.addTask(actionId.getAndIncrement(), task);
    }

    /**
     * 抢夺矿坑
     */
    public static MineWarProto.MinePitRobRespMsg.Builder robPit(GamePlayer player, int mineType, int pitId, long pitOwnerUserId, List<Integer> patronsIdList){
        MineWarProto.MinePitRobRespMsg.Builder msg = MineWarProto.MinePitRobRespMsg.newBuilder();
        if(!SystemOpenMgr.systemOpen(player, eSystemId.MineWar.getValue())){
            msg.setRet(GameErrorCode.E_SYSTEM_NO_OPEN);
            return msg;
        }
        if(player.getTitleId() < ConfigMgr.getMineOpenNeedTitle(mineType)){
            msg.setRet(GameErrorCode.E_SYSTEM_NO_OPEN);
            return msg;
        }
        if(patronsIdList.size() > GameConfig.MINE_WAR_BATTLE_MAX_PATRONS_COUNT){
            msg.setRet(GameErrorCode.E_MINE_WAR_PATRONS_COUNT_OVER);
            return msg;
        }
        //检测矿坑是否存在
        MinePitInfo pitInfo = MineWarConfigMgr.getMinePitInfo(mineType, pitId);
        if(null == pitInfo){
            msg.setRet(GameErrorCode.E_MINE_WAR_MINE_PIT_NO_FOUND);
            return msg;
        }
        UserMinePit userMinePit = getUserMinePit(mineType, pitId);
        if(null == userMinePit){
            msg.setRet(GameErrorCode.E_MINE_WAR_MINE_PIT_NO_FOUND);
            return msg;
        }
        if(userMinePit.getUserId() == player.getUserId()){
            msg.setRet(GameErrorCode.E_MINE_WAR_MINE_CAN_NO_ROB_SELF_PIT);
            return msg;
        }
        if(userMinePit.getUserId() != pitOwnerUserId){//矿坑占有人发生变化
            msg.setRet(0);
            MineWarProto.MinePitTempMsg.Builder pitMsg = MineWarPb.parseMinePitTempMsg(userMinePit);
            if(null != pitMsg) {
                msg.setMinePit(pitMsg);
            }
            return msg;
        }
        //检测出战门客战斗次数，是否需要发费元宝
        int ret = player.getModule(MineWarModule.class).checkAndCostBattleTimes(patronsIdList);
        if(0 != ret){
            msg.setRet(ret);
            return msg;
        }

        Property winReward = null;
        BattleResult battleResult;
        synchronized (lockObj) {
            userMinePit = getUserMinePit(mineType, pitId);
            //没人占领或者无限坑
            if (userMinePit.getUserId() == 0) {
                //添加通告
                if(userMinePit.getPitId() < GameConfig.MINE_WAR_NOTICE_NEED_PIT){
                    MineWarNotice mineWarNotice = initMineWarNotice(userMinePit, player.getUserId(), userMinePit.getUserId());
                    addMineWarNotice(mineWarNotice);
                }
                winReward = updateMinePitUser(player, userMinePit, patronsIdList);
                msg.setRet(0);
                msg.setWinReward(PropertyHelper.parsePropertyToString(winReward));
                msg.setWinUserId(player.getUserId());
                msg.addAllPatronsIdList(patronsIdList);
                MineWarProto.MinePitTempMsg.Builder pitMsg = MineWarPb.parseMinePitTempMsg(userMinePit);
                if(null != pitMsg){
                    msg.setMinePit(pitMsg);
                }
                return msg;
            }
            List<UserPatrons> patronsList = player.getModule(PatronsModule.class).getUserPatronsList(patronsIdList);
            battleResult = BattleManager.battle(player.getUserId(), patronsList, userMinePit.getUserId(), userMinePit.getPatronsList(), 0,
                    true, true);

            boolean isWin = false;
            if (battleResult.getWinUserId() == player.getUserId()) {
                isWin = true;
            }
            //添加记录
            MineWarRecord mineWarRecord = initMineWarRecord(userMinePit.getUserId(), userMinePit, isWin, player.getUserId());
            addMineWarRecord(mineWarRecord);

            //添加通告
            if(userMinePit.getPitId() < GameConfig.MINE_WAR_NOTICE_NEED_PIT && isWin){
                MineWarNotice mineWarNotice = initMineWarNotice(userMinePit, player.getUserId(), userMinePit.getUserId());
                addMineWarNotice(mineWarNotice);
            }
            // 赢的话 替换阵容
            if (isWin) {
                // 给失败的玩家发送邮件和占领奖励
                UserInfo loserUser = UserMgr.getUserInfo(userMinePit.getUserId());
                String mailTitle = MultipleLanguageMgr.getContent(MailManager.MINE_WAR_BE_ROB_TITLE, loserUser.getLanguage());
                String mailContent = StringUtils.format(MultipleLanguageMgr.getContent(MailManager.MINE_WAR_BE_ROB_CONTENT, loserUser.getLanguage()),
                        MineWarConfigMgr.getMinePitName(userMinePit.getMineType(), userMinePit.getPitId(), loserUser.getLanguage()), player.getUserInfo().getNickName());
                Property enemyReward = getPitOccupyReward(userMinePit.getUserId(), userMinePit, System.currentTimeMillis() / 1000, true);
                MailManager.sendMail(userMinePit.getUserId(), eMailType.DAILY.getValue(), PropertyHelper.parsePropertyToString(enemyReward), mailContent, mailTitle);

                winReward = updateMinePitUser(player, userMinePit, patronsIdList);
                // 同步地块信息
                MineWarProto.MinePitTempMsg.Builder pitMsg = MineWarPb.parseMinePitTempMsg(userMinePit);
                if(null != pitMsg){
                    msg.setMinePit(pitMsg);
                }
                msg.setWinUserId(player.getUserId());
            }else {
                msg.setWinUserId(userMinePit.getUserId());
            }
        }
        msg.setRet(0);
        msg.setWinReward(PropertyHelper.parsePropertyToString(winReward));
        //我方信息
        msg.addAllPatronsIdList(patronsIdList);
        //战斗详细信息
        msg.setBattleDetailList(BattlePb.parseBattleDetailListMsg(battleResult.getPatronsBattleDetailList()));
        //对手出战门客、座骑
        for (UserPatrons userPatrons : battleResult.getEnemyPatronsList()) {
            PatronsProto.PatronsTempMsg.Builder patronsMsg = PatronsPb.parsePatronsTempMsg(userPatrons);
            if(null != patronsMsg) {
                msg.addEnemyPatronsList(patronsMsg);
            }
        }
        return msg;
    }

    public static MineWarProto.MinePitWithdrawRespMsg.Builder withdrawPit(GamePlayer player, int mineType, int pitId){
        MineWarProto.MinePitWithdrawRespMsg.Builder msg = MineWarProto.MinePitWithdrawRespMsg.newBuilder();
        Property occupyReward;
        UserMinePit userMinePit;
        long lastGetRewardTime;
        long nowTime = System.currentTimeMillis() / 1000;
        synchronized (lockObj) {
            userMinePit = getUserMinePit(mineType, pitId);
            if (null == userMinePit) {
                msg.setRet(GameErrorCode.E_MINE_WAR_MINE_PIT_NO_FOUND);
                return msg;
            }
            if(userMinePit.getUserId() != player.getUserId()){
                msg.setRet(GameErrorCode.E_MINE_WAR_MINE_PIT_OWNER_CHANGE);
                return msg;
            }
            //计算占领收益
            lastGetRewardTime = userMinePit.getLastGetRewardTime();
            occupyReward = getPitOccupyReward(player.getUserId(), userMinePit, nowTime, true);
            //清除状态
            clearMinePitUser(userMinePit);
        }
        //收益入袋
        player.getModule(CurrencyModule.class).addCurrency(occupyReward, eLogMoneyType.MineWar, eLogMoneyType.MineWarWithdrawPit);
        LogMgr.addLogMineWarReward(player.getUserId(), mineType, pitId, PropertyHelper.parsePropertyToString(occupyReward), nowTime - lastGetRewardTime,
                false, eLogMoneyType.MineWarWithdrawPit.getValue());
        player.getModule(MineWarModule.class).syncMinePit(userMinePit, true);
        //矿场资源
        int goodsId = ConfigMgr.getMineOutputItemMap().get(mineType);
        msg.setRet(0);
        msg.setReward(occupyReward.getCountByGoodsId(goodsId).intValue());
        return msg;
    }

    /**
     * 领取矿坑占领时间收益
     */
    public static Property getPitOccupyReward(long userId, UserMinePit userMinePit, long getRewardTime, boolean isUpdateRewardTime) {
        Property occupyReward = new Property();
        if(null == userMinePit){
            logger.warn("getPitOccupyReward userMinePit is null");
            return occupyReward;
        }
        if(userMinePit.getUserId() != userId){
            logger.warn("getPitOccupyReward userMinePit userId not same");
            return occupyReward;
        }
        UserMineData userMineData = getUserMineData(userId);
        if(null == userMineData){
            logger.warn("getPitOccupyReward userMineData is null");
            return occupyReward;
        }
        MinePitInfo pitInfo = MineWarConfigMgr.getMinePitInfo(userMinePit.getMineType(), userMinePit.getPitId());
        long occupyTime = (getRewardTime - userMinePit.getLastGetRewardTime()) / 60;
        if(occupyTime > 0){//算钱咯
            BigInteger rewardValue = MineWarConfigMgr.getMineOutput(userId, userMinePit.getMineType(), userMinePit.getPatronsList(), pitInfo.getOutputSpeedAddition()).
                    multiply(BigDecimal.valueOf(occupyTime)).toBigInteger();
            GamePlayer player = GamePlayerMgr.getOnlinePlayer(userId);
            if(1 == userMinePit.getMineType()){
                userMineData.setTotalReward1(userMineData.getTotalReward1().add(rewardValue));
                if(rewardValue.compareTo(userMineData.getMaxTeamReward1()) > 0){
                    userMineData.setMaxTeamReward1(rewardValue);
                    if(null != player){
                        player.notifyListener(eGamePlayerEventType.MineWarMaxTeamReward.getValue(), userMineData);
                    }
                }
            }else if(2 == userMinePit.getMineType()){
                userMineData.setTotalReward2(userMineData.getTotalReward2().add(rewardValue));
                if(rewardValue.compareTo(userMineData.getMaxTeamReward2()) > 0){
                    userMineData.setMaxTeamReward2(rewardValue);
                    if(null != player){
                        player.notifyListener(eGamePlayerEventType.MineWarMaxTeamReward.getValue(), userMineData);
                    }
                }
            }else if(3 == userMinePit.getMineType()){
                userMineData.setTotalReward3(userMineData.getMaxTeamReward3().add(rewardValue));
                if(rewardValue.compareTo(userMineData.getMaxTeamReward3()) > 0){
                    userMineData.setMaxTeamReward3(rewardValue);
                    if(null != player){
                        player.notifyListener(eGamePlayerEventType.MineWarMaxTeamReward.getValue(), userMineData);
                    }
                }
            }
            if(null != player){
                player.notifyListener(eGamePlayerEventType.MineWarTotalReward.getValue(), userMineData);
            }
            int goodsId = ConfigMgr.getMineOutputItemMap().get(userMinePit.getMineType());
            if(goodsId > 0){
                occupyReward.addProperty(goodsId, rewardValue);
            }
            if(isUpdateRewardTime) {
                userMinePit.setLastGetRewardTime(getRewardTime);
                synchronized (needUpdateUserMinePitList) {
                    if (!needUpdateUserMinePitList.contains(userMinePit)) {
                        needUpdateUserMinePitList.add(userMinePit);
                    }
                }
            }
        }
        return occupyReward;
    }

    /**
     * 获取矿战来访记录
     */
    public static List<MineWarRecord> getUserMineWarRecord(long userId){
        return mineWarRecordMap.get(userId);
    }

    public static MineWarProto.MineWarNoticeListMsg.Builder getUserMineWarNotice(GamePlayer player){
        MineWarProto.MineWarNoticeListMsg.Builder msg = MineWarPb.parseMineWarNoticeListMsg(mineWarNoticeList);
        return msg;
    }

    public static void checkDispatchOverTime(){
        for(Map.Entry<Integer, Map<Integer, UserMinePit>> dataEntry : userMinePitMap.entrySet()){
            synchronized (lockObj){
                for(UserMinePit userMinePit : dataEntry.getValue().values()){
                    if(0 == userMinePit.getUserId()){
                        continue;
                    }
                    long nowTime = System.currentTimeMillis() / 1000;
                    long maxTime = userMinePit.getLastGetRewardTime() + GameConfig.MINE_MAX_OCCUPY_TIME;
                    if(nowTime >= maxTime){//超过时间，自动撤出坑位
                        //计算占领收益
                        Property occupyReward = getPitOccupyReward(userMinePit.getUserId(), userMinePit, maxTime, true);
                        //通过邮件发送收益
                        UserInfo userInfo = UserMgr.getUserInfo(userMinePit.getUserId());
                        String mailTitle = MultipleLanguageMgr.getContent(MailManager.MINE_WAR_WITHDRAW_PIT_TITLE, userInfo.getLanguage());
                        String mailContent = StringUtils.format(MultipleLanguageMgr.getContent(MailManager.MINE_WAR_WITHDRAW_PIT_CONTENT, userInfo.getLanguage()),
                                MineWarConfigMgr.getMinePitName(userMinePit.getMineType(), userMinePit.getPitId(), userInfo.getLanguage()),
                                GameConfig.MINE_MAX_OCCUPY_TIME / 3600);
                        MailManager.sendMail(userMinePit.getUserId(), eMailType.DAILY.getValue(), PropertyHelper.parsePropertyToString(occupyReward), mailContent, mailTitle);
                        GamePlayer player = GamePlayerMgr.getOnlinePlayer(userMinePit.getUserId());
                        if(null != player) {
                            player.getModule(MineWarModule.class).syncMinePit(userMinePit, true);
                        }
                        //清除状态
                        clearMinePitUser(userMinePit);
                    }
                }
            }
        }
    }

    /**
     * 对手是否在来访记录中
     */
    public static boolean isInMineWarRecord(long userId, long enemyUserId){
        List<MineWarRecord> recordList = getUserMineWarRecord(userId);
        if(null == recordList){
            return false;
        }
        return recordList.stream().anyMatch(mineWarRecord -> mineWarRecord.getEnemyUserId() == enemyUserId);
    }

    /**
     * 更新矿坑占有人
     */
    private static Property updateMinePitUser(GamePlayer player, UserMinePit userMinePit, List<Integer> patronsIdList){
        if(null == player || null == userMinePit || null == patronsIdList){
            return null;
        }
        Property reward;
        long oldUserId = userMinePit.getUserId();
        if(oldUserId > 0) {
            UserMineData oldMineData = getUserMineData(oldUserId);
            if(null != oldMineData) {
                oldMineData.setTotalBeRobTimes(oldMineData.getTotalBeRobTimes() + 1);
                GamePlayer oldPlayer = GamePlayerMgr.getOnlinePlayer(oldUserId);
                updateMinePitPatronsState(oldPlayer, userMinePit, MineWarConfigMgr.DISPATCH_MINE_NONE);
                if (null != oldPlayer) {
                    oldPlayer.getModule(MineWarModule.class).syncMinePit(userMinePit, true);
                    //成就、任务
                    oldPlayer.notifyListener(eGamePlayerEventType.MineWarTotalBeRobTimes.getValue(), oldMineData);
                }
            }
        }
        long nowTime = System.currentTimeMillis() / 1000;
        userMinePit.setUserId(player.getUserId());
        UserInfo userInfo = UserMgr.getUserInfo(player.getUserId());
        userMinePit.setNickName(userInfo.getNickName());
        userMinePit.setDecoration(UserMgr.getDecoration(userInfo.getUserId()));
        userMinePit.setPatronsIdList(patronsIdList);
        userMinePit.setPatronsList(player.getModule(PatronsModule.class).getUserPatronsList(patronsIdList));
        userMinePit.setJoinTime(nowTime);
        userMinePit.setLastGetRewardTime(nowTime);
        userMinePit.setTotalAbility(player.getModule(PatronsModule.class).getPatronsListAbility(userMinePit.getPatronsIdList()));
        updateMinePitPatronsState(player, userMinePit, MineWarConfigMgr.DISPATCH_MINE_PUBLIC);
        synchronized (needUpdateUserMinePitList) {
            if (!needUpdateUserMinePitList.contains(userMinePit)) {
                needUpdateUserMinePitList.add(userMinePit);
            }
        }
        MineStationInfo stationInfo = MineWarConfigMgr.getMineStationInfo(userMinePit.getMineType(), userMinePit.getStationId());
        if(null != stationInfo){
            changeMineStation(stationInfo);
        }
        //计算占领收益
        reward = getPitOccupyReward(player.getUserId(), userMinePit, nowTime + GameConfig.MINE_WAR_VICTORY_REWARD, false);
        //收益入袋
        player.getModule(CurrencyModule.class).addCurrency(reward, eLogMoneyType.MineWar, eLogMoneyType.MineWarWinReward);
        LogMgr.addLogMineWarReward(player.getUserId(), userMinePit.getMineType(), userMinePit.getPitId(), PropertyHelper.parsePropertyToString(reward),
                GameConfig.MINE_WAR_VICTORY_REWARD, false, eLogMoneyType.MineWarWinReward.getValue());
        //增加累计占领次数
        UserMineData userMineData = player.getModule(MineWarModule.class).getUserMineData();
        userMineData.setTotalRobTimes(userMineData.getTotalRobTimes() + 1);
        //成就、任务
        player.notifyListener(eGamePlayerEventType.MineWarRobTimes.getValue(), 1);
        player.notifyListener(eGamePlayerEventType.MineWarTotalRobTimes.getValue(), userMineData);
        if(stationInfo.getPosition() == 1) {//第一个矿位才公告
            if(0 == oldUserId) {
                WorldMessageMgr.worldNotify(eMessageType.MineWarRobPit.getValue(), player.getUserInfo().getCity(), player.getTitleId(),
                        player.getUserInfo().getNickName(), userMinePit.getMineType(), userMinePit.getPitId());
            }else {
                UserInfo oldUserInfo = UserMgr.getUserInfo(oldUserId);
                WorldMessageMgr.worldNotify(eMessageType.MineWarRobPitBattle.getValue(), player.getUserInfo().getCity(), player.getTitleId(),
                        player.getUserInfo().getNickName(), oldUserInfo.getCity(), oldUserInfo.getTitleId(), oldUserInfo.getNickName(),
                        userMinePit.getMineType(), userMinePit.getPitId());
            }
        }
        player.getModule(MineWarModule.class).syncMinePit(userMinePit, false);
        return reward;
    }

    private static Map<Integer, UserMinePit> getUserMinePitMap(int mineType) {
        return userMinePitMap.get(mineType);
    }

    public static UserMinePit getUserMinePit(int mineType, int pitId){
        if(userMinePitMap.containsKey(mineType)){
            return userMinePitMap.get(mineType).get(pitId);
        }
        return null;
    }

    /**
     * 清除矿坑占有状态
     * @param userMinePit
     */
    private static void clearMinePitUser(UserMinePit userMinePit) {
        if (null == userMinePit) {
            return;
        }
        GamePlayer player = GamePlayerMgr.getOnlinePlayer(userMinePit.getUserId());
        updateMinePitPatronsState(player, userMinePit, MineWarConfigMgr.DISPATCH_MINE_NONE);
        userMinePit.setUserId(0);
        userMinePit.setNickName("");
        userMinePit.setUnionName("");
        userMinePit.setDecoration("");
        userMinePit.setTotalAbility(BigInteger.ZERO);
        userMinePit.setLastGetRewardTime(System.currentTimeMillis() / 1000);
        userMinePit.setPatronsIdList(new ArrayList<>());
        userMinePit.setPatronsList(new ArrayList<>());
        synchronized (needUpdateUserMinePitList) {
            if (!needUpdateUserMinePitList.contains(userMinePit)) {
                needUpdateUserMinePitList.add(userMinePit);
            }
        }
        MineStationInfo stationInfo = MineWarConfigMgr.getMineStationInfo(userMinePit.getMineType(), userMinePit.getStationId());
        if(null != stationInfo){
            changeMineStation(stationInfo);
        }
    }

    private static void updateMinePitPatronsState(GamePlayer player, UserMinePit userMinePit, int dispatchMine){
        int type = 0;
        int pitId = 0;
        if(dispatchMine > 0){
            type = userMinePit.getMineType();
            pitId = userMinePit.getPitId();
        }
        if(null != player){
            player.getModule(MineWarModule.class).updateMinePitPatronsState(userMinePit.getPatronsIdList(), dispatchMine, type, pitId);
        }else {//通过修改数据库修改状态
            UserMineWarBussiness.updateUserMineWarPatronsData(userMinePit.getUserId(), userMinePit.getPatronsIdList(), dispatchMine, type, pitId);
        }
    }

    /**
     * 获取用户的矿坑列表
     */
    public static List<UserMinePit> getUserMinePitList(long userId){
        List<UserMinePit> pitList = new ArrayList<>();
        for(Map<Integer, UserMinePit> userPitMap : userMinePitMap.values()){
            for(UserMinePit userMinePit : userPitMap.values()){
                if(userMinePit.getUserId() == userId){
                    pitList.add(userMinePit);
                }
            }
        }
        return pitList;
    }

    private static List<UserMinePit> getUserMinePitList(int stationId){
        List<UserMinePit> pitList = new ArrayList<>();
        for(Map<Integer, UserMinePit> userPitMap : userMinePitMap.values()){
            for(UserMinePit userMinePit : userPitMap.values()){
                if(userMinePit.getStationId() == stationId){
                    pitList.add(userMinePit);
                }
            }
        }
        return pitList;
    }

    /**
     * 门客能力值变化
     */
    public static void patronsAbilityChange(GamePlayer player, int mineType, int pitId, UserPatrons userPatrons){
        synchronized (lockObj){
            UserMinePit userMinePit = getUserMinePit(mineType, pitId);
            if(null == userMinePit || userMinePit.getUserId() != player.getUserId()){
                return;
            }
            userMinePit.setNickName(player.getUserInfo().getNickName());                //更新基础信息
            userMinePit.setDecoration(UserMgr.getDecoration(player.getUserId()));
            userMinePit.replacePatrons(userPatrons);
            //更新能力
            userMinePit.setTotalAbility(player.getModule(PatronsModule.class).getPatronsListAbility(userMinePit.getPatronsIdList()));
            MineStationInfo mineStationInfo = MineWarConfigMgr.getMineStationInfo(userMinePit.getMineType(), userMinePit.getStationId());
            changeMineStation(mineStationInfo);
        }
    }

    private static void changeMineStation(MineStationInfo mineStationInfo) {
        List<UserMinePit> tempPitList = getUserMinePitList(mineStationInfo.getStationId());
        BigInteger totalAbility = BigInteger.ZERO;
        int occupyCount = 0;
        for(UserMinePit pit : tempPitList){
            if(pit.getUserId() != 0){
                occupyCount++;
                if(mineStationInfo.isShowAbility()) {
                    totalAbility = totalAbility.add(pit.getTotalAbility());
                }
            }
        }
        mineStationInfo.setOccupyCount(occupyCount);
        if(mineStationInfo.isShowAbility() && occupyCount >= GameConfig.MINE_WAR_OCCUPY_PIT_COUNT_SHOW_ABILITY){
            mineStationInfo.setAverageAbility(totalAbility.divide(BigInteger.valueOf(occupyCount)));
        }else {
            mineStationInfo.setAverageAbility(BigInteger.ZERO);
        }
    }

    private static UserMineData getUserMineData(long userId){
        return userMineDataMap.get(userId);
    }

    private static void addMineWarRecord(MineWarRecord mineWarRecord) {
        if(null == mineWarRecord){
            return;
        }
        synchronized (mineWarRecordMap) {
            if (!mineWarRecordMap.containsKey(mineWarRecord.getUserId())) {
                mineWarRecordMap.put(mineWarRecord.getUserId(), new ArrayList<>());
            }
        }
        List<MineWarRecord> recordList = mineWarRecordMap.get(mineWarRecord.getUserId());
        synchronized (recordList) {
            if (recordList.size() >= GameConfig.MINE_WAR_MAX_RECORD_COUNT) {
                recordList.remove(0);
            }
            recordList.add(mineWarRecord);
        }
        synchronized (needAddRecordList) {
            needAddRecordList.add(mineWarRecord);
        }
    }

    private static MineWarRecord initMineWarRecord(long userId, UserMinePit userMinePit, boolean isWin, long enemyUserId) {
        UserInfo enemyUserInfo = UserMgr.getUserInfo(enemyUserId);
        if(null == enemyUserInfo){
            return null;
        }
        if(null == userMinePit){
            return null;
        }

        MineWarRecord record = new MineWarRecord();
        record.setUserId(userId);
        record.setRecordUid(UUIDHelper.randomUUID(String.valueOf(GameServer.getInstance().getServerId())));
        record.setMineType(userMinePit.getMineType());
        record.setPitId(userMinePit.getPitId());
        record.setEnemyUserId(enemyUserId);
        record.setEnemyBaseData(UserMgr.parseUserBaseInfo(enemyUserInfo, GameServer.getInstance().getServerId()));
        record.setRecordTime(System.currentTimeMillis() / 1000);
        record.setWin(isWin);
        return record;
    }

    private static void addMineWarNotice(MineWarNotice notice) {
        if(null == notice){
            return;
        }
        synchronized (mineWarNoticeList) {
            if(mineWarNoticeList.size() >= GameConfig.MINE_WAR_MAX_NOTICE_COUNT){
                mineWarNoticeList.removeFirst();
            }
            mineWarNoticeList.addLast(notice);
            needAddNoticeList.add(notice);
        }
    }

    private static MineWarNotice initMineWarNotice(UserMinePit userMinePit, long userId, long enemyUserId){
        if(null == userMinePit || userId <= 0){
            return null;
        }
        UserInfo userInfo = UserMgr.getUserInfo(userId);
        if(null == userInfo){
            return null;
        }
        UserInfo enemyUserInfo = null;
        if(enemyUserId > 0) {
            enemyUserInfo = UserMgr.getUserInfo(enemyUserId);
            if (null == enemyUserInfo) {
                return null;
            }
        }
        MineWarNotice mineWarNotice = new MineWarNotice();
        mineWarNotice.setNoticeUid(UUIDHelper.randomUUID(String.valueOf(GameServer.getInstance().getServerId())));
        mineWarNotice.setMineType(userMinePit.getMineType());
        mineWarNotice.setPitId(userMinePit.getPitId());
        mineWarNotice.setNoticeTime(System.currentTimeMillis() / 1000);
        mineWarNotice.setUserId(userInfo.getUserId());
        mineWarNotice.setUserBaseInfo(UserMgr.parseUserBaseInfo(userInfo, GameServer.getInstance().getServerId()));
        if(null == enemyUserInfo){
            mineWarNotice.setEnemyUserId(0);
            mineWarNotice.setEnemyBaseInfo(new UserBaseInfo());
        }else {
            mineWarNotice.setEnemyUserId(enemyUserInfo.getUserId());
            mineWarNotice.setEnemyBaseInfo(UserMgr.parseUserBaseInfo(enemyUserInfo, GameServer.getInstance().getServerId()));
        }
        return mineWarNotice;
    }

}
